local skynet = require "skynet"
local base = require "base"
local msghelper = require "tablehelper"
local timetool = require "timetool"
local tabletool = require "tabletool"
local timer = require "timer"
local filelog = require "filelog"
local ddzgamelogic = require "ddzgamelogic"
local json = require "cjson"
json.encode_sparse_array(true,1,1)
require "pdkenum"
local tablerequest = require "tablerequest"

local tablelogic
local seatlogic
local ddzlogic
local server

local GameLogic = {}

function GameLogic.init(gameobj, tablebase)
	server = tablebase
	tablelogic = tablebase.logic.tablelogic
	seatlogic  = tablebase.logic.seatlogic
	ddzlogic  = tablebase.logic.ddzlogic

	gameobj.table_data = tablebase.table_data
	gameobj.stateevent[ETableState.TABLE_STATE_GAME_START] = GameLogic.gamestart
	gameobj.stateevent[ETableState.TABLE_STATE_ONE_GAME_START] = GameLogic.onegamestart
	gameobj.stateevent[ETableState.TABLE_STATE_WAIT_START_COUNT_DOWN] = GameLogic.waitstartcountdown
	gameobj.stateevent[ETableState.TABLE_STATE_ONE_GAME_END] = GameLogic.onegameend
	gameobj.stateevent[ETableState.TABLE_STATE_ONE_GAME_END_AFTER] = GameLogic.onegameendafter
	gameobj.stateevent[ETableState.TABLE_STATE_ONE_GAME_REAL_END] = GameLogic.onegamerealend
	gameobj.stateevent[ETableState.TABLE_STATE_CONTINUE] = GameLogic.continue
	return true
end

function GameLogic.run(gameobj)
	local f = nil
	local loopcount = 10
	while true do
		if gameobj.table_data.state == ETableState.TABLE_STATE_WAIT_ALL_READY then
			break
		end
		f = gameobj.stateevent[gameobj.table_data.state]
		if f == nil then
			break
		end
		loopcount = loopcount - 1
		if loopcount <= 0 then
			filelog.sys_error("-------gamelogic out of looptimes-----", "-----------table.state------------", gameobj.table_data.state)
			break
		end
		f(gameobj)
	end
end

function GameLogic.gamestart(gameobj)
	local table_data = gameobj.table_data
	for _, seat in ipairs(table_data.seats) do
		if seat.state ~= ESeatState.SEAT_STATE_NO_PLAYER then
			if seat.ready_timer_id and seat.ready_timer_id > 0  then ---取消准备倒计时，以防万一
				timer.cleartimer(seat.ready_timer_id)
				seat.ready_timer_id = -1
				seat.ready_to_time = 0
			end
		end
	end
	table_data.state = ETableState.TABLE_STATE_ONE_GAME_START
end

function GameLogic.onegamestart(gameobj)
	local table_data = gameobj.table_data
	GameLogic.onegamestart_inittable(gameobj)

	table_data.state = ETableState.TABLE_STATE_WAIT_START_COUNT_DOWN
end

----桌子进入开始倒计时阶段
function GameLogic.waitstartcountdown(gameobj)
	local table_data = gameobj.table_data

	local startcountdownmsg = {}
	if table_data.timer_id and table_data.timer_id >0 then
		timer.cleartimer(table_data.timer_id)
		table_data.timer_id = -1
	end
	-----启动开始倒计时定时器，在定时器超时函数中处理发牌逻辑
	local count = table_data.conf.match_type and 3 or 0.5
	if table_data.the_round > 1 then count = 0.5 end
	local timerid = timer.settimer(count*100, "waitstartcountdown", startcountdownmsg)
	if table_data.state ~= ETableState.TABLE_STATE_WAIT_START_COUNT_DOWN then
		timer.cleartimer(timerid)
	else
		table_data.timer_id = timerid
	end

	table_data.state = ETableState.TABLE_STATE_WAIT_COUNT_DOWN
end

function GameLogic.continue(gameobj)
	local table_data = gameobj.table_data
	if table_data.timer_id and table_data.timer_id >= 0 then
		timer.cleartimer(table_data.timer_id)
		table_data.timer_id = -1
	end
	local seat = table_data.seats[table_data.action_seat_index]

	local noticemsg = {
		rid = seat.rid,
		seat_index = table_data.action_seat_index,
		action_type = table_data.action_type,
		cards = {},
	}
	---如果table上的状态是等待玩家出牌
	if table_data.action_type == EActionType.ACTION_TYPE_CHUPAI or
		table_data.action_type == EActionType.ACTION_TYPE_FOLLOW_CHUPAI or
		table_data.action_type == EActionType.ACTION_TYPE_CHECK then
		if table_data.action_type ~= EActionType.ACTION_TYPE_CHECK and #table_data.CardsHeaps > 0 then
			if table_data.action_type == EActionType.ACTION_TYPE_FOLLOW_CHUPAI then
				table_data.seats[table_data.action_seat_index].followhandsnum = table_data.seats[table_data.action_seat_index].followhandsnum + 1
			end
			local roundheaps = table_data.CardsHeaps[#table_data.CardsHeaps]
			for k,v in ipairs(roundheaps[#roundheaps].cardHelper) do
				table.insert(noticemsg.cards,v)
			end
			----通知服务器当前牌桌的倍数,玩家的手牌数
			tablelogic.sendHandsInfo(table_data)
		end
		table_data.state = ETableState.TABLE_STATE_ONE_GAME_START
	end

	seatlogic.setSeatstate(table_data)
	-- TO ADD操作类型
	msghelper:sendmsg_to_alltableplayer("doactionN", noticemsg)
	
	local isendgame = false
	if table_data.action_type == EActionType.ACTION_TYPE_CHUPAI or table_data.action_type == EActionType.ACTION_TYPE_FOLLOW_CHUPAI then
		for k,v in ipairs(table_data.seats) do
			if v.state ~= ESeatState.SEAT_STATE_NO_PLAYER then
				if v.cards and #v.cards == 0 then 
					isendgame = true 
					v.win = 1
					table_data.winner = v.index
					break 
				end
			end
		end
	end
	--判断是否结束游戏
	if isendgame then
		if table_data.bomb_index then
			table_data.bomb[table_data.bomb_index] = (table_data.bomb[table_data.bomb_index] or 0) + 1
			local bombadd = 0
			for _, _seat in ipairs(table_data.seats) do
				if _seat.state ~= ESeatState.SEAT_STATE_NO_PLAYER and _seat.rid > 0 then
					if _seat.index ~= table_data.bomb_index then
						_seat.diamond = _seat.diamond - 10*table_data.conf.base_score
						if table_data.conf.room_type == ERoomType.ROOM_TYPE_COMMON then
							if _seat.diamond < 0 then
								_seat.bomboff = _seat.diamond
								_seat.diamond = 0
							end
							bombadd = bombadd + 10*table_data.conf.base_score + (_seat.bomboff or 0)
						else
							bombadd = bombadd + 10*table_data.conf.base_score
						end
						msghelper:sendmsg_to_alltableplayer("moneychangeN", {
							money_change_list = {
								{
									rid = _seat.rid,
									money_type = 2,
									value = _seat.diamond,
								},
							}
						})
					end
				end
			end
			table_data.seats[table_data.bomb_index].diamond = table_data.seats[table_data.bomb_index].diamond + bombadd
			msghelper:sendmsg_to_alltableplayer("moneychangeN", {
				money_change_list = {
					{
						rid = table_data.seats[table_data.bomb_index].rid,
						money_type = 2,
						value = table_data.seats[table_data.bomb_index].diamond,
					},
				}
			})
			table_data.bomb_index = nil
		end
		table_data.state = ETableState.TABLE_STATE_ONE_GAME_END
		return
	end
	local next_action_index = 0
	if table_data.action_seat_index == 1 then
		next_action_index = 2
	elseif table_data.action_seat_index == 2 then
		next_action_index = 3
	elseif table_data.action_seat_index == 3 then
		next_action_index = 1
	end
	
	if table_data.conf.game_type == EGameType.GAME_TYPE_NORMAL_FOR2 or table_data.conf.game_type == EGameType.GAME_TYPE_CARD15_FOR2 then
		if table_data.seats[next_action_index].state == ESeatState.SEAT_STATE_NO_PLAYER then
			-- 下一位必然不是空位
			if next_action_index == 1 then
				next_action_index = 2
			elseif next_action_index == 2 then
				next_action_index = 3
			elseif next_action_index == 3 then
				next_action_index = 1
			end
		end
	end
	if table_data.bomb_index and table_data.bomb_index == next_action_index then
		table_data.bomb[next_action_index] = (table_data.bomb[next_action_index] or 0) + 1
		local bombadd = 0
		for _, _seat in ipairs(table_data.seats) do
			if _seat.state ~= ESeatState.SEAT_STATE_NO_PLAYER and _seat.rid > 0 then
				if _seat.index ~= next_action_index then
					_seat.diamond = _seat.diamond - 10*table_data.conf.base_score
					if table_data.conf.room_type == ERoomType.ROOM_TYPE_COMMON then
						if _seat.diamond < 0 then
							_seat.bomboff = _seat.diamond
							_seat.diamond = 0
						end
						bombadd = bombadd + 10*table_data.conf.base_score + (_seat.bomboff or 0)
					else
						bombadd = bombadd + 10*table_data.conf.base_score
					end
					msghelper:sendmsg_to_alltableplayer("moneychangeN", {
						money_change_list = {
							{
								rid = _seat.rid,
								money_type = 2,
								value = _seat.diamond,
							},
						}
					})
				end
			end
		end
		table_data.seats[next_action_index].diamond = table_data.seats[next_action_index].diamond + bombadd
		msghelper:sendmsg_to_alltableplayer("moneychangeN", {
			money_change_list = {
				{
					rid = table_data.seats[next_action_index].rid,
					money_type = 2,
					value = table_data.seats[next_action_index].diamond,
				},
			}
		})
		table_data.bomb_index = nil
	end

	if table_data.state == ETableState.TABLE_STATE_ONE_GAME_START then
		---通知下一位玩家跟牌
		if table_data.action_type == EActionType.ACTION_TYPE_CHUPAI then
			table_data.noputsCardsNum = 0
			table_data.action_type = EActionType.ACTION_TYPE_FOLLOW_CHUPAI
		elseif table_data.action_type == EActionType.ACTION_TYPE_CHECK or table_data.action_type == EActionType.ACTION_TYPE_TIMEOUT_FOLLOW_CHUPAI then
			table_data.noputsCardsNum = table_data.noputsCardsNum + 1
			if table_data.conf.game_type == EGameType.GAME_TYPE_NORMAL_FOR2 or table_data.conf.game_type == EGameType.GAME_TYPE_CARD15_FOR2 then
				if table_data.noputsCardsNum == 1 then
					table_data.action_type = EActionType.ACTION_TYPE_CHUPAI
				else
					table_data.action_type = EActionType.ACTION_TYPE_FOLLOW_CHUPAI
				end
			else
				if table_data.noputsCardsNum == 2 then
					table_data.action_type = EActionType.ACTION_TYPE_CHUPAI
				else
					table_data.action_type = EActionType.ACTION_TYPE_FOLLOW_CHUPAI
				end
			end
		elseif table_data.action_type == EActionType.ACTION_TYPE_FOLLOW_CHUPAI then
			table_data.noputsCardsNum = 0
		end
		table_data.action_seat_index = next_action_index
	end
	local nextseat = table_data.seats[next_action_index]

	--通知下一个玩家操作下发当前玩家操作协议
	table_data.action_to_time = timetool.get_time() + table_data.conf.action_timeout
	local doactionntcmsg = {
		rid = table_data.seats[table_data.action_seat_index].rid,
		seat_index = table_data.action_seat_index,
		action_type = table_data.action_type,
		action_to_time = table_data.action_to_time,
	}
	
	msghelper:sendmsg_to_alltableplayer("todoN", doactionntcmsg)
	
	local timerid
	if table_data.seats[table_data.action_seat_index].is_tuoguan == EBOOL.TRUE then
		timerid = timer.settimer(table_data.conf.tuoguan_action_time*100, "doaction", doactionntcmsg)
	else
		timerid = timer.settimer(table_data.conf.action_timeout*100, "doaction", doactionntcmsg)
	end
	if table_data.state ~= ETableState.TABLE_STATE_CONTINUE and table_data.state ~= ETableState.TABLE_STATE_ONE_GAME_START then
		if timerid then
			timer.cleartimer(timerid)
		end
	else
		table_data.timer_id = timerid
	end

	table_data.state = ETableState.TABLE_STATE_WAIT_CLIENT_ACTION

	if nextseat.isrobot then
		skynet.fork(function ()
			if table_data.action_type == EActionType.ACTION_TYPE_CHUPAI then
				local status, cards, onelast = tablelogic.putcards(table_data)
				table_data.action_type = EActionType.ACTION_TYPE_CHUPAI
			elseif table_data.action_type == EActionType.ACTION_TYPE_FOLLOW_CHUPAI then
				local status, cards, onelast = tablelogic.followcards(table_data, false, true)
				if status then
					table_data.action_type = EActionType.ACTION_TYPE_FOLLOW_CHUPAI
				else
					table_data.action_type = EActionType.ACTION_TYPE_CHECK
				end
			end
			if table_data.action_type == EActionType.ACTION_TYPE_CHECK or onelast then
				skynet.sleep(150)
			else
				skynet.sleep(math.random(2, 5) * 100)
			end
			if not table_data.gaming then return end

			table_data.state = ETableState.TABLE_STATE_CONTINUE
			GameLogic.run(table_data.gamelogic)
			if table_data.conf.room_type ~= ERoomType.ROOM_TYPE_SYSTEM then
				local action = timetool.get_time() .. "_" 
					.. nextseat.rid .. "_"
					.. (table_data.action_type or '0')
				tablelogic.save_actions(table_data, action, cards)
			end
		end)
	end
end

function GameLogic.onegameend(gameobj)
	-- body
	local table_data = gameobj.table_data
	table_data.gaming = false

	if table_data.timer_id and table_data.timer_id >0 then
		timer.cleartimer(table_data.timer_id)
		table_data.timer_id = -1
	end
	---获取最后一手手牌
	local roundheaps = table_data.CardsHeaps[#table_data.CardsHeaps]
	if not roundheaps or #roundheaps <= 0 then return end
	local playercardhelper = roundheaps[#roundheaps].cardHelper
	local delayTime = EDelayTimeCardType.COMMON_CARDTYPE
	for k,v in pairs(ECardType) do
		if playercardhelper.m_eCardType == v then
			if EDelayTimeCardType[k] then
				delayTime = EDelayTimeCardType[k]
				break
			end
		end
	end
	local gameendmsg = {}
	---设置定时器，用于客户端展示牌局游戏结果界面
	local timerid = timer.settimer(delayTime, "onegameend", gameendmsg)
	if table_data.state ~= ETableState.TABLE_STATE_ONE_GAME_END then
		timer.cleartimer(timerid)
	else
		table_data.timer_id = timerid
	end
	table_data.state = ETableState.TABLE_STATE_WAIT_ONE_GAME_REAL_END

	-- local data = {
	-- 	basecoins = table_data.conf.base_score,
	-- 	maxcoin = table_data.conf.max_score,
	-- 	times = table_data.baseTimes,
	-- 	pinfos = {},
	-- }
	-- msghelper:copy_playerinfoingameend(data.pinfos)
	-- tablelogic.saveOneGamerecords(table_data, data)
end

function GameLogic.onegameendafter(gameobj)
	local table_data = gameobj.table_data
	local table_data = gameobj.table_data

	if table_data.timer_id and table_data.timer_id >0 then
		timer.cleartimer(table_data.timer_id)
		table_data.timer_id = -1
	end

	----通知玩家游戏结束了
	if table_data.action_type == EActionType.ACTION_TYPE_CHUPAI or table_data.action_type == EActionType.ACTION_TYPE_FOLLOW_CHUPAI then
		----结果结算逻辑处理部分
		tablelogic.balancegame(table_data)
		local GameEndResultNtcmsg = {
			basescore = table_data.conf.base_score,
			maxscore = table_data.conf.max_score,
			times = table_data.baseTimes,
			playerinfos = {},
			gameinfo = {},
		}
		
		msghelper:copy_playerinfoingameend(GameEndResultNtcmsg.playerinfos)
		msghelper:copy_table_gameinfo(GameEndResultNtcmsg.gameinfo)
		if GameEndResultNtcmsg.gameinfo.state ~= ETableState.TABLE_STATE_WAIT_ALL_READY then
			GameEndResultNtcmsg.gameinfo.state = ETableState.TABLE_STATE_WAIT_ALL_READY
		end
		if table_data.cur_games_times < table_data.conf.game_times then
			GameEndResultNtcmsg.gameinfo.state = ETableState.TABLE_STATE_WAIT_NEXT_GAMES
		end
		msghelper:sendmsg_to_alltableplayer("gamebalanceN", GameEndResultNtcmsg)
		local balance = {
			basescore = GameEndResultNtcmsg.basescore,
			playerinfos = GameEndResultNtcmsg.playerinfos,
		}
		tablelogic.save_actions(table_data, balance)
	end
	if table_data.conf.room_type == ERoomType.ROOM_TYPE_FRIEND then
		---设置定时器，用于客户端展示牌局游戏结果界面
		if table_data.cur_games_times >= table_data.conf.game_times then
			local gameendmsg = {}
			local ftablebalmsg = {
				table_idx = table_data.idx,
				table_code = table_data.conf.table_code,
				playerinfos = {},
			}
			local records = {}
			if table_data.tablerecords and type(table_data.tablerecords) == "table" then
				for key,value in pairs(table_data.tablerecords) do
					local tem = {
						rid = value.rid,  ----玩家rid
						rolename = value.rolename,
						logo = value.logo,
						highestscore = value.highestscore,
						totalscore = value.totalscore,
						totalwin = value.totalwin,
						totallose = value.totallose,
						iswin = value.iswin
					}
					if tem.totalwin > tem.totallose then
						tem.iswin = 1
					elseif tem.totalwin < tem.totallose then
						tem.iswin = 0
					end
					table.insert(ftablebalmsg.playerinfos, tem)
					records[value.rid] = {
						rolename = tem.rolename,
						beginvalue = 0,
						value = tem.totalscore,
						endvalue = tem.totalscore,
					}
				end
			end
			table_data.timesover = true
			msghelper:sendmsg_to_alltableplayer("tablebalanceN", ftablebalmsg)
			-- filelog.debug("tablebalance ======>>>", ftablebalmsg)
			tablelogic.save_tablerecord(table_data, records)
		end
	end
	local timerid = timer.settimer(EDelayTimeCardType.COMMON_CARDTYPE, "onegameendafter", gameendmsg)
	if table_data.state ~= ETableState.TABLE_STATE_ONE_GAME_END_AFTER then
		timer.cleartimer(timerid)
	else
		table_data.timer_id = timerid
	end

	---切换桌子状态
	for k, value in ipairs(table_data.seats) do
		if value.state ~= ESeatState.SEAT_STATE_NO_PLAYER then
			seatlogic.resetstate(value)
			-- if value.is_disconnect then
			-- 	tablelogic.passive_standuptable(table_data, value)
			-- end
		end
	end
	
	table_data.state = ETableState.TABLE_STATE_WAIT_ONE_GAME_REAL_END
end

function GameLogic.onegamerealend(gameobj)
	local table_data = gameobj.table_data
	table_data.the_round = table_data.the_round + 1
	if table_data.timer_id and table_data.timer_id > 0 then
		timer.cleartimer(table_data.timer_id)
		table_data.timer_id = -1
	end
	tablelogic.save_actions(table_data, "end")

	if table_data.conf.room_type == ERoomType.ROOM_TYPE_FRIEND then
		----朋友桌检查局数是否足够
		if table_data.cur_games_times >= table_data.conf.game_times then
			table_data.state = ETableState.TABLE_STATE_WAIT_ALL_READY
			for _, seat in ipairs(table_data.seats) do
				if seat.state ~= ESeatState.SEAT_STATE_NO_PLAYER then
					tablelogic.passive_standuptable(table_data, seat, EStandupReason.STANDUP_REASON_DELETE_TABLE)
				end
			end
			table_data.delete_table_timer_id = timer.settimer(table_data.conf.retain_time*100, "delete_table")
			-- table_data.delete_table_timer_id = timer.settimer(30*100, "delete_table")
			return
		end
	end

	local isallrobot = true
	for _, seat in ipairs(table_data.seats) do
		if seat.state ~= ESeatState.SEAT_STATE_NO_PLAYER then
			if seat.rid > 100 then
				isallrobot = false
			end
		end
	end
	if isallrobot then
		table_data.delete_table_timer_id = timer.settimer(table_data.conf.retain_time*100, "delete_table")
		return
	end

	if server.will_kill then
		tablelogic.leaveallplayers(table_data)
		return
	end

	local noticeDoReadymsg = {
		rid = 0,
		seat_index = 0,
		ready_to_time = 0,
	}
	for k,v in ipairs(table_data.seats) do
		if v.rid ~= 0 and v.state == ESeatState.SEAT_STATE_WAIT_READY then
			noticeDoReadymsg.rid =  v.rid
			noticeDoReadymsg.seat_index = v.index
			noticeDoReadymsg.ready_to_time = timetool.get_time() + table_data.conf.ready_timeout
			v.ready_to_time = timetool.get_time() + table_data.conf.ready_timeout
			msghelper:sendmsg_to_alltableplayer("doreadyN",noticeDoReadymsg)
										
			if v.ready_timer_id > 0 then
				timer.cleartimer(v.ready_timer_id)
				v.ready_timer_id = -1
			end
			local outoftimermsg = {
				rid = v.rid,
				seat_index = v.index,
			}
			----每个玩家增加准备倒计时定时器
			v.ready_timer_id = timer.settimer(table_data.conf.ready_timeout*100, "doready", outoftimermsg)

			if v.rid < 100 then
				tablelogic.gameready(table_data, request, v)
			end
		end
	end
	
	----重置桌子状态为等待玩家准备开始游戏的状态
	GameLogic.reset_table(table_data,true)
	GameLogic.onegamestart_inittable(gameobj)
	table_data.state = ETableState.TABLE_STATE_WAIT_ALL_READY
end

function GameLogic.reset_table(table_data)
	table_data.state = ETableState.TABLE_STATE_GAME_START
	table_data.action_type =  0			---玩家当前操作类型
	table_data.initCards = nil			---牌池
	table_data.CardsHeaps = nil			---保存玩家出过的牌的牌堆
	table_data.retain_to_time = 0		 	---桌子保留到的时间(linux时间擢)
	table_data.action_seat_index = 0		---当前操作玩家的座位号
	table_data.action_to_time = 0			---当前操作玩家的到期时间
	table_data.baseTimes = 1		   		--- 基础倍数
	table_data.noputsCardsNum = 0			---一个出牌回合里,没有出牌的玩家数,不出+1，出牌则置0
	table_data.first_action_index = nil
end

function GameLogic.is_ingame(gameobj, seat)
	return (seat.state == ESeatState.SEAT_STATE_PLAYING
			or seat.state == ESeatState.SEAT_STATE_CHECK
			or seat.state == ESeatState.SEAT_STATE_CHUPAI
			or seat.state == ESeatState.SEAT_STATE_FOLLOW_CHUPAI)
end

function GameLogic.onegamestart_inittable(gameobj)
	local table_data = gameobj.table_data
	table_data.action_seat_index = 0
	table_data.action_to_time = 0
	table_data.action_type = 0
	table_data.initCards = nil	   --牌池
	table_data.baseTimes = table_data.conf.common_times
	table_data.bomb = {}
	table_data.CardsHeaps = nil 		---保存玩家出过的牌的牌堆
	table_data.noputsCardsNum = 0
	table_data.tmpdiamond = nil
	table_data.first_action_index = nil
	table_data.tip = nil
	table_data.gamerecords = {}
	table_data.recycled = nil
end

function GameLogic.standup_clear_seat(gameobj, seat)
	seatlogic.clear_seat(seat)
end

------朋友桌发牌
function GameLogic.RiffleandPostCards(table_data)	
	if table_data.state == ETableState.TABLE_STATE_WAIT_COUNT_DOWN then
		local now = timetool.get_time()
		----生成一副牌
		ddzlogic.InitCards(table_data)
		----洗牌
		ddzlogic.Riffle(table_data)
		table_data.gamerecords.initcards = json.encode(table_data.initCards)
		----发牌
		local firstIndex = base.get_random(1, 3)
		ddzlogic.PostCards(table_data, firstIndex)
		local handcards = {}
		-----发牌给客户端
		local rids = {}
		local playerdata = {}
		for key, value in ipairs(table_data.seats) do
			if table_data.conf.game_type == EGameType.GAME_TYPE_NORMAL_FOR2 or table_data.conf.game_type == EGameType.GAME_TYPE_CARD15_FOR2 then
				seatlogic.dealcards(value, table_data.cur_games_times)
				seatlogic.onegamestart_initseat2(value)
				handcards[value.rid] = tabletool.deepcopy(value.handcards)
			else
				if value.rid <= 0 then	-- 这里说明有错，暂时作删除桌子处理。
					table_data.delete_table_timer_id = timer.settimer(100, "delete_table")
					if table_data.timer_id and table_data.timer_id > 0 then
						timer.cleartimer(table_data.timer_id)
						table_data.timer_id = -1
					end
				end
				if value.state == ESeatState.SEAT_STATE_WAIT_START then
					seatlogic.dealcards(value, table_data.cur_games_times)
					seatlogic.onegamestart_initseat(value)
					handcards[value.rid] = tabletool.deepcopy(value.handcards)
				end
			end
			table.insert(rids, value.rid)
			playerdata[value.rid] = {
				name = value.playerinfo.rolename,
				logo = value.playerinfo.logo,
				sex = value.playerinfo.sex,
				diamond = value.diamond,
			}
		end

		if table_data.conf.room_type ~= ERoomType.ROOM_TYPE_SYSTEM then
			table.sort(rids, function(l, r)
				return l < r
			end)
			local ridsstr = ''
			for _, rid in ipairs(rids) do
				if ridsstr == '' then
					ridsstr = ridsstr .. rid
				else
					ridsstr = ridsstr .. '_' .. rid
				end
			end
			-- init gamerecords
			table_data.gamerecords.start_time = now
			table_data.gamerecords.table_uuid = skynet.getenv("nodename") .. "_"
				.. table_data.conf.table_code .. "_"
				.. table_data.conf.idx .. "_" .. table_data.conf.create_time
			table_data.gamerecords.logname = '' .. table_data.gamerecords.table_uuid .. '_'
				.. now .. '_' .. '0' .. '_'
				.. ridsstr .. '_' .. os.date("%Y%m%d_%H%M%S", now) .. '_'
				.. table_data.conf.game_room_type
			table_data.gamerecords.handcards = json.encode(handcards)
			table_data.gamerecords.rids = ridsstr
			table_data.gamerecords.playerdata = json.encode(playerdata)
		end

		if table_data.conf.room_type == ERoomType.ROOM_TYPE_COMMON then
			-- tablelogic.pay_tip(table_data)
			for key, value in ipairs(table_data.seats) do
				if value.state ~= ESeatState.SEAT_STATE_NO_PLAYER then
					value.start_diamond = value.getdiamond
				end
			end
		end
		table_data.conf.curr_round_code = string.sub(tostring(now), -4, -1)
		if table_data.conf.room_type ~= ERoomType.ROOM_TYPE_SYSTEM then
			table_data.gamerecords.conf = json.encode(table_data.conf)
			tablelogic.save_actions(table_data)
		end

		local gamestartntcmsg = {}
		gamestartntcmsg.gameinfo = {}
		msghelper:copy_table_gameinfo(gamestartntcmsg.gameinfo)
		msghelper:sendmsg_to_alltableplayer("gamestartN", gamestartntcmsg)
		if table_data.conf.blackheart3 == 1 then
			table_data.action_seat_index = ddzlogic.checkblackheart3(table_data.seats)
		else
			if table_data.winner then
				table_data.action_seat_index = table_data.winner
			else
				table_data.action_seat_index = ddzlogic.checkblackheart3(table_data.seats)
			end
		end
		table_data.first_action_index = table_data.action_seat_index
		table_data.state = ETableState.TABLE_STATE_WAIT_PLAYER_CHUPAI
		table_data.action_type = EActionType.ACTION_TYPE_CHUPAI
		GameLogic.run(table_data.gamelogic)

		table_data.action_to_time = timetool.get_time() + table_data.conf.action_timeout
		--下发当前玩家操作协议
		local doactionntcmsg = {
			rid = table_data.seats[table_data.action_seat_index].rid,
			seat_index = table_data.action_seat_index,
			action_to_time = table_data.action_to_time,
			action_type = table_data.action_type
		}
		msghelper:sendmsg_to_alltableplayer("firstactionseatN", {
			rid = doactionntcmsg.rid,
			seat_index = doactionntcmsg.seat_index,
		})
		----通知所有玩家 seatIndex上的玩家在出牌了
		msghelper:sendmsg_to_alltableplayer("todoN", doactionntcmsg)
		local timerid
		if table_data.seats[table_data.action_seat_index].is_tuoguan == EBOOL.TRUE then
			timerid = timer.settimer(table_data.conf.tuoguan_action_time*100, "doaction", doactionntcmsg)
		else
			timerid = timer.settimer(table_data.conf.action_timeout*100, "doaction", doactionntcmsg)
		end
		if table_data.state ~= ETableState.TABLE_STATE_WAIT_PLAYER_CHUPAI then
			if timerid then
				timer.cleartimer(timerid)
			end
		else
			table_data.timer_id = timerid
		end

		local nextseat = table_data.seats[table_data.action_seat_index]
		if nextseat.isrobot then
			skynet.fork(function ()
				skynet.sleep(math.random(3, 5) * 100)
				if not table_data.gaming then return end
				local status, cards = false, {}
				if table_data.action_type == EActionType.ACTION_TYPE_CHUPAI then
					status, cards = tablelogic.putcards(table_data)
					tablelogic.action_type = EActionType.ACTION_TYPE_CHUPAI
				end
				table_data.state = ETableState.TABLE_STATE_CONTINUE
				GameLogic.run(table_data.gamelogic)
				if table_data.conf.room_type ~= ERoomType.ROOM_TYPE_SYSTEM then
					local action = timetool.get_time() .. "_" 
						.. nextseat.rid .. "_"
						.. (table_data.action_type or '0')
					tablelogic.save_actions(table_data, action, cards)
				end
			end)
		end
	end
end

return GameLogic